<html>
<head>

<title>Groovy Goodness: Set Script Class with BaseScript Annotation</title>

<script language="javascript" src="scripts/shCore.js"></script> 
<script language="javascript" src="scripts/shLegacy.js"></script> 
<script language="javascript" src="scripts/shBrushJava.js"></script> 
<script language="javascript" src="scripts/shBrushXml.js"></script> 
<script language="javascript" src="scripts/shBrushJScript.js"></script> 
<script language="javascript" src="scripts/shBrushGroovy.js"></script> 
<script language="javascript" src="scripts/shBrushPlain.js"></script> 
<script language="javascript" src="scripts/shBrushBash.js"></script> 
 
<link href="styles/reset.css" rel="stylesheet" type="text/css" />
<link href="styles/shCore.css" rel="stylesheet" type="text/css" />
<link type="text/css" rel="stylesheet" href="styles/shThemeRDark.css"/>
<link href="styles/blog.css" rel="stylesheet" type="text/css" />

</head>
<body>

<a href="index.html">Back to index</a>

<h3 class="post-title">Groovy Goodness: Set Script Class with BaseScript Annotation</h3>

<div class="post">
<p>Groovy is of course great for writing DSLs. We can write <a href="http://mrhaki.blogspot.com/2011/11/groovy-goodness-create-our-own-script.html">our own <code>Script</code> class to implement a DSL</a> that can be used when we evaluate a script. We can set the custom <code>Script</code> class via <code>CompilerConfiguration</code>. Since Groovy 2.2 we can use a new AST transformation <code>@BaseScript</code>. We must use this annotation in the script and set it on the custom script class. The name of the variable is not important, but the type must by the custom script class.</p><p>In the following DSL script we use the <code>@BaseScript</code> instead of the <code>CompilerConfiguration</code> as shown in <a href="http://mrhaki.blogspot.com/2011/11/groovy-goodness-create-our-own-script.html">previous blog post</a>.</p><pre class="brush:groovy">// Simple Car class to save state and distance.
class Car {
    String state
    Long distance = 0
}

// Custom Script with methods that change the Car's state.
// The Car object is passed via the binding.
abstract class CarScript extends Script {
    def start() {
        this.binding.car.state = 'started'
    }

    def stop() {
        this.binding.car.state = 'stopped'
    }

    def drive(distance) {
        this.binding.car.distance += distance
    }
}


// Define Car object here, so we can use it in assertions later on.
def car = new Car()
// Add to script binding (CarScript references this.binding.car).
def binding = new Binding(car: car)

// Configure the GroovyShell.
def shell = new GroovyShell(this.class.classLoader, binding)

// Simple DSL to start, drive and stop the car.
// The methods are defined in the CarScript class.
def carDsl = '''
start()
drive 20
stop()
'''


// Run DSL script.
shell.evaluate """
// Use BaseScript annotation to set script
// for evaluating the DSL.
@groovy.transform.BaseScript CarScript carScript

$carDsl
"""

// Checks to see that Car object has changed.
assert car.distance == 20
assert car.state == 'stopped'
</pre><p>Code written with Groovy 2.2.</p
</div>

<script language="javascript"> 
SyntaxHighlighter.config.bloggerMode = true;
SyntaxHighlighter.config.clipboardSwf = 'scripts/clipboard.swf';
SyntaxHighlighter.defaults['first-line'] = 0;
SyntaxHighlighter.defaults['auto-links'] = false;
SyntaxHighlighter.all();
dp.SyntaxHighlighter.HighlightAll('code');
</script>

</body>
</html>